package si.banst.sledi.ejb;

import java.util.List;
import java.util.concurrent.Future;
import java.util.logging.Logger;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.ejb.AsyncResult;
import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.ejb.Stateless;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.Session;

import si.banst.sledi.Pogoj;
import si.banst.sledi.ZapisSledi;
import si.banst.sledi.ejb.napake.NapakaPriPovprasevanju;
import si.banst.sledi.ejb.napake.NapakaPriZapisu;

/**
 * Session Bean implementation class SlediBean
 */
@Stateless
public class SlediBean implements SlediBeanLocal, SlediBeanRemote {

	private static final Logger logger = Logger.getLogger(SlediBean.class
			.getName());

	@Resource
	private Queue vrstaSledi;

	@Resource
	private ConnectionFactory vrstaSlediTovarna;

	private Session seja;
	private Connection povezava;
	private MessageProducer producer;

	@EJB
	private ShrambaSlediBean shrambaSlediBean;

	/**
	 * Default constructor.
	 */
	public SlediBean() {
		super();
	}

	@PostConstruct
	public void init() {
		logger.fine("Inicializiram SlediBean zrno");
		try {
			logger.fine("Ustvarjam povezavo na vrstaSlediTovarn.");
			povezava = vrstaSlediTovarna.createConnection();

			logger.finest("Ustvarjam sejo.");
			seja = povezava.createSession(true, Session.AUTO_ACKNOWLEDGE);

			logger.finest("Ustvarjam proizvajalca.");
			producer = seja.createProducer(vrstaSledi);
		} catch (Exception e) {
			logger.severe("Napaka pri inicializaciji. " + e.getMessage());
			throw new EJBException("Napaka pri inicializaciji. ", e);
		}
	}

	@PreDestroy
	public void close() {
		try {
			producer.close();
			seja.close();
			povezava.close();
		} catch (JMSException e) {
			logger.severe("Napaka pri zapiranju virov. " + e.getMessage());
			throw new EJBException("Napaka pri zapiranju virov. ", e);
		}

	}

	@Override
	public void vstaviSled(ZapisSledi zapisSledi) throws NapakaPriZapisu {
		try {
			ObjectMessage sporocilo = seja.createObjectMessage(zapisSledi);
			producer.send(sporocilo);
			logger.fine("Sporočilo uspešno vstavljeno.");
		} catch (Exception e) {
			logger.severe("Napaka pri vstavljanju sporočila. " + e.getMessage());
			throw new NapakaPriZapisu("Napaka pri vstavljanju sporočila. ", e);
		}

	}

	

	@Override
	public void vstaviSledi(List<ZapisSledi> zapisiSledi)
			throws NapakaPriZapisu {
		try {
			for (ZapisSledi zapisSledi : zapisiSledi) {
				ObjectMessage sporocilo = seja.createObjectMessage(zapisSledi);
				producer.send(sporocilo);
			}
			logger.fine("Sporočilo uspešno vstavljeno.");
		} catch (Exception e) {
			logger.severe("Napaka pri vstavljanju sporočila. " + e.getMessage());
			throw new NapakaPriZapisu("Napaka pri vstavljanju sporočila. ", e);
		}

	}

	@Override
	public Future<List<String>> vrniSledi(List<Pogoj> pogoji, String vrstaZbirke)
			throws NapakaPriPovprasevanju {
		logger.fine("Asinhrono procesiram zahtevo - vrni sledi. ");
		return new AsyncResult<List<String>>(shrambaSlediBean.vrniSledi(pogoji, vrstaZbirke));
	}


}
